package ift585.serveur;


import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;

public class FileTransfertHandler implements Runnable {
	private static final int PACKET_LENTGH = 1024;
	private static final int SERVER_TIMEOUT = 10000;
	private static final int CLOSING_ACK = FenetreServeur.FIN_FICHIER;
	private int serverPort;
	private int remoteClientPort;
	private InetAddress remoteClientAddress = null;
	private DatagramSocket serveurSocket = null;
	private FenetreServeur fenetre;
	
	public FileTransfertHandler(byte[] messageFromClient, InetAddress client, int clientPort, int portServeur, int packetLentgh) throws FileNotFoundException, SocketException {
		// S'instancie une fen�tre
		serverPort = portServeur;
		
		remoteClientAddress = client;
		remoteClientPort = clientPort;

		fenetre = new FenetreServeur(new String(messageFromClient));
	}
	
	@Override
	public void run() {

		boolean communicationEnCours = true;
		
		byte [] dataBuffer = new byte[PACKET_LENTGH];
		DatagramPacket dataReceived = new DatagramPacket(dataBuffer, PACKET_LENTGH);
		
		try {
			initCommunication();
			
			while(communicationEnCours){
				
				System.out.println("Waiting for DATA");
				serveurSocket.receive(dataReceived);
				
				byte [] answerToClient = fenetre.getNextAck(dataReceived.getData());

				System.out.println("Je confirme la réception du paquet : " + (int)((dataReceived.getData())[0]));
				

				if((int)((dataReceived.getData())[0]) == CLOSING_ACK){
					communicationEnCours = false;
					System.out.println("Je termine la communication avec le client");
				}
				// envoie un ack pour le numéro du paquet
				System.out.println("Je suis rendu au paquet : " + (int)answerToClient[0]);
				renvoitAck(answerToClient);
			}

		}
		catch (SocketTimeoutException e) {
			byte[] closingAck = new byte[1];
			closingAck[0] = CLOSING_ACK;
			renvoitAck(closingAck);
			System.out.println("Timeout receive, closing connection");
		}
		catch (SocketException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void initCommunication() throws SocketException, IOException {
		byte buffer[] = new byte[PACKET_LENTGH];
		DatagramPacket reponse = new DatagramPacket(buffer, buffer.length, remoteClientAddress, remoteClientPort);
		serveurSocket = new DatagramSocket(serverPort);
		serveurSocket.send(reponse);
		serveurSocket.setSoTimeout(SERVER_TIMEOUT);
	}
	
	private void renvoitAck(byte[] answerToClient) {
		try {
			DatagramPacket reponse = new DatagramPacket(answerToClient, answerToClient.length, remoteClientAddress, remoteClientPort);
			serveurSocket.send(reponse);
		} catch (SocketException e1) {
			e1.printStackTrace();
		} catch (IOException e1) {
			e1.printStackTrace();
		}
	}
	

}
